import java.io.OutputStreamWriter;
import java.io.IOException;

/**
 * Constraint Set
 * */
public class ConstraintSet {

    public static final int MAX_NUM_VARIABLES = 100;

    private int         m_numVariables;
    private int         m_numConstraintChecks;
    private boolean[][] m_ne;

    // Create a constraint set ( only binary not-equal constraints )
	ConstraintSet( int numVariables )
	{
		assert( numVariables <= MAX_NUM_VARIABLES );

        m_numVariables = numVariables;
        m_numConstraintChecks = 0;
        m_ne = new boolean[MAX_NUM_VARIABLES][MAX_NUM_VARIABLES];

        for ( int x=0 ; x<MAX_NUM_VARIABLES ; ++x ) {
			for ( int y=0 ; y<MAX_NUM_VARIABLES ; ++y ) {
				m_ne[x][y] = false;
			}
		}

	}

	// Add a constraint telling that the two variables cannot be equal.
	void addNotEqual( int x, int y )
	{
		assert( x < m_numVariables );
		assert( y < m_numVariables );

		m_ne[x][y] = m_ne[y][x] = true;
	}

	// Test for conflicts between assignments of the variables; returns true if a conflict, otherwise false.
	// Count of the number of constraints checks is accumulated.
	boolean test( int x, int y, int assignment[] )
	{
		assert( x < m_numVariables );
		assert( y < m_numVariables );

		if ( m_ne[ x ][ y ] ) {
			m_numConstraintChecks++;
			if ( assignment[ x ] == assignment[ y ] ) {
				return false;
			}
		}
		return true;
	}

	// Get the number of variables.
	int getNumberOfVariables() { return m_numVariables; }

	// Get the number of constraint checks performed since beginning (or last reset).
	int getNumberOfChecks() { return m_numConstraintChecks; }

	// Reset number fo constraint checks to zero.
	void resetNumberOfChecks() { m_numConstraintChecks = 0; }

	// Display the constraints
	void display( OutputStreamWriter os )
	{
        try {
           for ( int x=0 ; x<m_numVariables ; ++x ) {
		    	for ( int y=x+1 ; y<m_numVariables ; ++y ) {
			    	if ( m_ne[x][y] ) {
				    	os.write("Var[");
                        os.write( x );
                        os.write( "] != Var[" );
                        os.write( y );
                        os.write( "]\n" );
				    }
			    }
		    }
		    os.write("\n");
            os.flush();
        } catch (IOException e ) {
            e.printStackTrace();
        }
    }

}
